package com.itic.appbase.applications.dbinit;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;

import javax.sql.DataSource;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.itic.appbase.applications.sys.common.persistence.model.InitDBVo;
import com.itic.appbase.applications.sys.org.persistence.model.Org;
import com.itic.appbase.applications.sys.org.service.OrgService;
import com.itic.appbase.applications.sys.region.persistence.model.Region;
import com.itic.appbase.applications.sys.region.service.RegionService;
import com.itic.appbase.applications.sys.user.persistence.model.SysUser;
import com.itic.appbase.applications.sys.user.service.SysUserService;
import com.itic.appbase.framework.common.constants.DBConst;
import com.itic.appbase.framework.common.constants.InitConst;
import com.itic.appbase.framework.utils.MD5Helper;
import com.itic.appbase.framework.utils.SpringContextHelper;
import com.itic.appbase.framework.utils.configuration.PropertyHelper;

@Component
public class DbInit {
    private static final Logger LOGGER = LoggerFactory.getLogger(DbInit.class);

    private OrgService orgService;
    private SysUserService sysUserService;
    private RegionService regionService;
    private DataSource dataSource;

    /**
     * 初始化数据
     * 
     * @param event
     * @throws Exception
     */
    public void initDB() {
        Boolean initDB = PropertyHelper.getBoolean("app.initDB");
        if (initDB) {
            // 加载Service
            this.setOrgService((OrgService) SpringContextHelper.getBean("orgService"));
            this.setRegionService((RegionService) SpringContextHelper.getBean("regionService"));
            this.setSysUserService((SysUserService) SpringContextHelper.getBean("sysUserService"));
            this.setDataSource((DataSource) SpringContextHelper.getBean("dataSource"));
            InitDBVo initDBVo = getInitData();
            initRootUser(initDBVo);
            initRootOrg(initDBVo);
            initRootRegion(initDBVo);
            initBaseData();
        }
    }

    /**
     * 初始化基本信息执行sql
     */
    private void initBaseData() {
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
        } catch (SQLException e1) {
            LOGGER.error("获得数据库连接出错！", e1);
        }
        try {
            ScriptRunner runner = new ScriptRunner(conn);
            runner.runScript(Resources.getResourceAsReader("/base/init.sql"));
        } catch (IOException e) {
            LOGGER.error("执行化信息出错！", e);
        } finally {
            if (null != conn) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    LOGGER.error("关闭数据库连接出错！", e);
                }
            }
        }
    }

    /**
     * 获得初始信息
     * 
     * @return
     */
    private InitDBVo getInitData() {
        InitDBVo vo = new InitDBVo();
        vo.setId(InitConst.ID);
        vo.setpId(InitConst.P_ID);
        vo.setCreateUser(InitConst.CREATE_USER);
        vo.setCode(InitConst.CODE);
        vo.setType(InitConst.TYPE);
        vo.setOrg(InitConst.ORG);
        vo.setOrgCode(InitConst.ORG_CODE);
        vo.setIsUsabl(InitConst.IS_USABLE);
        vo.setpCode(InitConst.P_CODE);

        vo.setRegionName(PropertyHelper.getString("initRegionName").trim());
        vo.setUserName(PropertyHelper.getString("initUserName").trim());
        vo.setPassword(PropertyHelper.getString("initUserPassword").trim());
        vo.setRelaName(PropertyHelper.getString("initUserRelaName").trim());
        vo.setOrgName(PropertyHelper.getString("initOrgName").trim());
        return vo;
    }

    /**
     * 初始化用户信息
     * 
     * @param initDBVo
     */
    private void initRootUser(InitDBVo initDBVo) {
        SysUser u = sysUserService.get(initDBVo.getId());
        if (null == u) {
            SysUser user = new SysUser();
            user.setId(initDBVo.getId());
            user.setUsername(initDBVo.getUserName());
            user.setRealname(initDBVo.getRelaName());
            user.setPassword(MD5Helper.md5DoubleSalt(initDBVo.getPassword(), initDBVo.getUserName()));
            user.setIsUsable(initDBVo.getIsUsabl());
            user.setOrg(initDBVo.getOrg());

            user.setCreateUser(initDBVo.getCreateUser());
            user.setOrgCode(initDBVo.getOrgCode());
            user.setIsEffective(DBConst.TRUE);
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            sysUserService.add(user);
        }
    }

    /**
     * 初始化组织机构信息
     * 
     * @param initDBVo
     */
    private void initRootOrg(InitDBVo initDBVo) {
        Org o = orgService.get(initDBVo.getId());
        if (null == o) {
            Org org = new Org();
            org.setId(initDBVo.getId());
            org.setName(initDBVo.getOrgName());
            org.setCode(initDBVo.getCode());
            org.setpCode(initDBVo.getpCode());
            org.setRegionId(initDBVo.getId());

            org.setCreateUser(initDBVo.getCreateUser());
            org.setOrgCode(initDBVo.getOrgCode());
            org.setIsEffective(DBConst.TRUE);
            org.setCreateTime(new Date());
            org.setUpdateTime(new Date());
            orgService.add(org);
        }
    }

    /**
     * 初始化行政区划信息
     * 
     * @param initDBVo
     */
    private void initRootRegion(InitDBVo initDBVo) {
        Region r = regionService.get(initDBVo.getId());
        if (null == r) {
            Region region = new Region();
            region.setId(initDBVo.getId());
            region.setpId(initDBVo.getpId());
            region.setName(initDBVo.getRegionName());
            region.setCode(initDBVo.getCode());
            region.setType(initDBVo.getType());

            region.setCreateUser(initDBVo.getCreateUser());
            region.setOrgCode(initDBVo.getOrgCode());
            region.setIsEffective(DBConst.TRUE);
            region.setCreateTime(new Date());
            region.setUpdateTime(new Date());
            regionService.add(region);
        }
    }

    public OrgService getOrgService() {
        return orgService;
    }

    public void setOrgService(OrgService orgService) {
        this.orgService = orgService;
    }

    public SysUserService getSysUserService() {
        return sysUserService;
    }

    public void setSysUserService(SysUserService sysUserService) {
        this.sysUserService = sysUserService;
    }

    public RegionService getRegionService() {
        return regionService;
    }

    public void setRegionService(RegionService regionService) {
        this.regionService = regionService;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

}
